import {computed, designComponent, iHTMLIFrameElement, PropType, reactive, useRefs} from "@peryl/react-compose";
import {addWebFrameBaseMessageListener, iMicroConfig, iMicroTokenInfo, iMicroWebFrameSubMessageData} from '@peryl/micro-web';
import {pathJoin} from "@peryl/utils/pathJoin";
import {useCurrentPage} from "./useCurrentPage";
import {microApp} from "../microApp";
import {defer} from "@peryl/utils/defer";
import {microLoadingHook} from "./useMicroLoading";
import {$notice} from "plain-design";

export const FrameModeIFrame = designComponent({
  props: {
    microConfig: { type: Object as PropType<iMicroConfig>, required: true },
    tokenInfo: { type: Object as PropType<iMicroTokenInfo>, required: true },
  },
  setup({ props }) {
    const { refs, onRef } = useRefs({ frame: iHTMLIFrameElement });

    const readyDefer = defer();

    const handler = {
      onLoad: () => {

        onIFrameLoad();

        const ejectSubInitReady = addWebFrameBaseMessageListener({
          microConfigId: props.microConfig.id,
          type: 'subInitReady',
          handler: () => {
            readyDefer.resolve();
            ejectSubInitReady();
          },
        });

        const initMessage: iMicroWebFrameSubMessageData = { microWebFrameMessage: { type: 'init', data: { microConfigId: props.microConfig.id } } };
        refs.frame!.contentWindow!.postMessage(JSON.stringify(initMessage), '*');

        addWebFrameBaseMessageListener({
          microConfigId: props.microConfig.id,
          type: 'subRouteChange',
          handler: (data) => {
            console.log('base get subRouteChange', data.historyMeta, data.historyMeta.fullPath);
            const fullPath = pathJoin(
              microApp.route.buildMicroPublicPath({ microConfig: props.microConfig, subMicroPublicPath: publicPath.value }),
              data.historyMeta.fullPath
            );
            const currentPath = window.location.pathname + window.location.search + window.location.hash;
            if (currentPath !== fullPath) {
              window.history.replaceState({}, '', fullPath);
              // currentPageHandler.handlePathChange(currentPath);
            }
          }
        });
      },
    };

    const publicPath = computed((): string => {
      if (props.microConfig.publicPath) {
        return pathJoin('/' + props.microConfig.publicPath + '/');
      } else {
        const indexUrl = props.microConfig.index(props.tokenInfo);
        if (typeof indexUrl !== "string") {
          throw new Error('microConfig.index must be string when use iframe mode.');
        }
        const url = new URL(indexUrl);
        return pathJoin('/' + url.pathname + '/');
      }
    });

    const currentPageHandler = useCurrentPage({
      microConfig: props.microConfig,
      tokenInfo: props.tokenInfo,
      getPublicPath: async () => {
        const subPublicPath = publicPath.value;
        return {
          publicPathOfSub: subPublicPath,
          publicPathOfSubWithBaseRoutePath: microApp.route.buildMicroPublicPath({ microConfig: props.microConfig, subMicroPublicPath: subPublicPath }),
        };
      },
      handleNewPage: async ({ baseFullPagePath, purePagePath }) => {
        /*提前修改子应用的pathname*/
        window.history.pushState({}, '', baseFullPagePath);
        // console.log(111, props.microConfig.id, { purePagePath });
        /*通知子应用调用路由函数切换路由状态*/
        const initMessage: iMicroWebFrameSubMessageData = { microWebFrameMessage: { type: 'changeSubRoute', data: { purePagePath } } };
        await readyDefer.promise;
        console.log('post changeSubRoute event', initMessage);
        refs.frame!.contentWindow!.postMessage(JSON.stringify(initMessage), '*');
      },
    });

    const iframeSrc = (() => {
      const _state = reactive({ src: null as null | string });
      Promise.resolve(props.microConfig.index(props.tokenInfo)).then(indexPath => {
        if (typeof indexPath !== "string") {
          console.warn('frameMode为iframe的情况下，microConfig.index返回值必须是字符串！');
        } else {
          _state.src = indexPath;
        }
      });
      return _state;
    })();

    const onComplete = (error?: string | null | undefined) => {microLoadingHook.exec({ id: props.microConfig.id, error });};
    const onIFrameLoad = () => onComplete();
    const onIFrameError = () => {/*暂时没有办法监听到iframe的加载失败事件*/
      const errMsg = `子应用[${props.microConfig.id}]加载失败！`;
      $notice.error(errMsg);
      onComplete(errMsg);
    };

    return () => (
      <div data-micro-container={props.microConfig.id} data-micro-frame-mode-iframe={props.microConfig.id}>
        {!!iframeSrc.src && <iframe ref={onRef.frame} src={iframeSrc.src} onLoad={handler.onLoad} onError={onIFrameError}/>}
      </div>
    );
  },
});

